#include"StdAfx.h"

pgFile::pgFile()
{
	m_pFile = NULL;
	m_bIsFileCreated = false;
	m_bIsFileOpened = false;
;
}

pgFile::~pgFile()
{
	Flush();
}

bool pgFile::CreateFile(const char* sFilename)
{
	if (m_bIsFileCreated == true || m_bIsFileOpened == true)
		return true;

	m_pFile = fopen(sFilename, "w");
	
	if (m_pFile == NULL)
	{
		g_PG_pLog->fTextoutTopic(RED,"pgFile" , "Failed to create new file with filename %s!", sFilename);
		return false;
	}

	//fclose(m_pFile);

	m_bIsFileCreated = true;


	m_sFilename = sFilename;

	// In case of critical failure
	

	return true;
}

bool pgFile::OpenFile(const char* sFilename, bool bCreateNew)
{
	if (m_bIsFileCreated == true || m_bIsFileOpened == true)
		return true;

	m_pFile = fopen(sFilename, "r");

	if (m_pFile == NULL)
	{
		g_PG_pLog->fTextoutTopic(RED, "pgFile","Failed to open file with filename %s!" , sFilename);

		if (bCreateNew == true)
		{
			bool succes = CreateFile(sFilename);
			
			if (succes)
				g_PG_pLog->fTextoutTopic(PURPLE, "pgFile", "Created new file %s as it could not be opened!", sFilename);
			return false;
		}

		return false;
	}

	fseek(m_pFile, 0, SEEK_END);
	
	long length = ftell(m_pFile);
	
	rewind(m_pFile);

	char *buffer = (char*) malloc(sizeof(char)* (length+1));
	
	int read = fread(buffer, 1, length, m_pFile);

	buffer[read] = 0;

	m_sTextBuffer = buffer;

	free(buffer);
	fclose(m_pFile);
	m_pFile = NULL; // By closing the file again we make sure it won't be affected by the program 
					// until it is ready to be written
	
	m_bIsFileOpened = true;
	m_bIsFileCreated = false;

	m_sFilename = sFilename;

	return true;
}
	
bool pgFile::DeleteFile(bool bKeepTextBuffer)
{
	if (m_pFile != NULL)
	{
		Flush();
		int succes = remove(m_sFilename.c_str());

		if (succes != 0)
		{
			// TODO 
			// use stderr to get an apropriate error message
			g_PG_pLog->fTextout(RED, false, "ERROR: Unable to delete file %s! Returnvalue is %d", m_sFilename.c_str(), succes);
			return false;
		}

		if (bKeepTextBuffer == false)
		{
			m_sTextBuffer.erase();
			return true;
		}
	}

	g_PG_pLog->fTextout(RED, "ERROR: Unable to delete file as there is none created yet!");
	return false;
}
	
size_t pgFile::FindString(const char* sString, ...)
{
	char buffer[MAX_BUFFER];
	va_list pArgList;

	va_start (pArgList, sString);
	vsprintf(buffer, sString, pArgList);
	va_end (pArgList);
	
	size_t pos = m_sTextBuffer.find(buffer);


	if (pos == std::string::npos)
	{
		g_PG_pLog->fTextoutTopic("pgFile", "Could not find string %s in file %s", sString, m_sFilename.c_str());
		//PG_LOG_INFO(sString);
		//PG_LOG_INFO(m_sFilename);
		pos = -1;
		return pos;
	}

	return pos;
}	

void pgFile::Append(const char* sString, ...)
{
	char buffer[MAX_BUFFER];
	va_list pArgList;

	va_start (pArgList, sString);
	vsprintf(buffer, sString, pArgList);
	va_end (pArgList);

	m_sTextBuffer.append(buffer);
}

void pgFile::PushFront(const char* sString, ...)
{
	char buffer[MAX_BUFFER];
	va_list pArgList;

	va_start (pArgList, sString);
	vsprintf(buffer, sString, pArgList);
	va_end (pArgList);
	m_sTextBuffer.insert(0, buffer);
}	

bool pgFile::EraseFromFile(const char* sString, size_t pos)
{
	size_t begin = FindString(sString);

	size_t len = strlen(sString);
	m_sTextBuffer.erase(begin, begin + len);
	return true;
}

bool pgFile::Insert(size_t pos, const char* sString,  ...)
{
	char buffer[MAX_BUFFER];
	va_list pArgList;

	va_start (pArgList, sString);
	vsprintf(buffer, sString, pArgList);
	va_end (pArgList);
	m_sTextBuffer.insert(pos, buffer);

	// TODO
	// Error checking needed
	return true;
}	

bool pgFile::Write(size_t pos, const char* sString,  ...)
{
	char buffer[MAX_BUFFER];
	va_list pArgList;

	va_start (pArgList, sString);
	vsprintf(buffer, sString, pArgList);
	va_end (pArgList);

	m_sTextBuffer.replace(pos, strlen(buffer), buffer);
	return true;
}

bool pgFile::Flush()
{
	// A new file has been created
	if (m_pFile != NULL && m_bIsFileCreated == true && m_bIsFileOpened == false)
	{
		fprintf(m_pFile, m_sTextBuffer.c_str());
		fflush(m_pFile);
		fclose(m_pFile);
		return true;
	}
	else if (m_pFile == NULL && m_bIsFileOpened == true && m_bIsFileCreated == false)
	{
		m_pFile = fopen(m_sFilename.c_str(), "w");

		if (m_pFile == NULL)
		{
			g_PG_pLog->fTextoutTopic(RED, "pgFile" , "Failed to create new file with filename %s!", m_sFilename.c_str());
			return false;
		}

		fprintf(m_pFile, m_sTextBuffer.c_str());
		fflush(m_pFile);
		fclose(m_pFile);
		return true;
	}

	// vv this is still true, but interferes with the error handling as a file object might be created but not initialized when a critical error occurs
	//g_PG_pLog->fTextout(RED, false, "ERROR: A pgFile object has been created without creating or opening a file!");
	return false;
}

bool pgFile::ReplaceString(const char* sToReplace, const char* sReplacement, size_t pos)
{
	size_t stringPos = m_sTextBuffer.find(sToReplace, pos);

	if (stringPos == std::string::npos)
	{
		g_PG_pLog->fTextout(RED, false,  "ERROR: Unable to find string %s to replace in file %s", sToReplace, m_sFilename.c_str());
		return false;
	}

	m_sTextBuffer.replace(stringPos, strlen(sToReplace), sReplacement);
	return true;
}


